﻿using Kwd.Summary.Driver;
using Kwd.Summary.Models;
using Kwd.Summary.Services;
using Orchard.ContentManagement;
using Orchard.Core.Common.Models;
using Orchard.DisplayManagement;
using Orchard.DisplayManagement.Descriptors;
using Orchard.DisplayManagement.Implementation;
using Orchard.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Resolvers;

namespace Kwd.Summary.Module
{
  /// <summary>
  /// In code management of part placement.
  /// 1. Re-shape Parts_Common_Body_Summary
  /// 2. Add SummaryStrategy* shapes
  /// </summary>
  /// <remarks>
  /// Not sure this is a good idea.
  /// Feels dirty changing the shape created by some other module.
  /// </remarks>
  public class Shapes : IShapeTableProvider
  {
    private IStrategyFactory _strategyFactory;

    public Shapes(IStrategyFactory strategyFactory)
    {
      Logger = NullLogger.Instance;
      _strategyFactory = strategyFactory;
    }

    public ILogger Logger { get; set; }

    public void Discover(ShapeTableBuilder builder)
    {
      //Hook in to replace html for body summary part.
      builder.Describe("Parts_Common_Body_Summary")
        .OnDisplaying(a => ReshapeBodySummary(a));

      //todo: can i re-shape to add strategy shapes at runtime?
      // maybe change placement for the SummaryPart shape?
      //builder.Describe(SummaryPartDriver.EditPartName)
        //.Placement(p => p.??)
        //.OnCreated(a => {AddStrategyShapes(a);}
    }

    public void ReshapeBodySummary(ShapeDisplayingContext context)
    {
      if (context == null ||
        context.Shape == null ||
        context.Shape.ContentItem == null)
      { return; }

      var contentItem = (ContentItem)context.Shape.ContentItem;
      var customSummaryPart = contentItem.Parts.OfType<SummaryPart>().SingleOrDefault();

      if (customSummaryPart != null)
      {
        var defaultSummary = (HtmlString)context.Shape.Html;
        var strategy = _strategyFactory.Create(customSummaryPart);

        try
        {
          //use strategy to update body summary.
          var summaryText = strategy.GenerateSummary(defaultSummary, customSummaryPart);
          context.Shape.Html = summaryText;
        }
        catch (GenerateSummaryException ex)
        {
          Logger.Warning(ex, "Summary for content item {0} cannot be created using \"{1}\", defaulting",
            contentItem.Id, strategy.GetType().Name);
        }
      }
    }
  }
}